"""
1. 收集数据
2. 处理数据
3. 特征工程
4. 机器学习（模型训练）
5. 模型评估

"""

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier


# 1. 收集数据
iris = load_iris()

# 2. 处理数据
feature_train, feature_test, dest_train, dest_test = train_test_split(iris.data, iris.target, random_state=22, test_size=0.2)

# 3. 特征工程
# 3.1 实例化转换器
transfer = StandardScaler()

# 3.2 特征预处理
feature_train = transfer.fit_transform(feature_train)
feature_test = transfer.fit_transform(feature_test)
# print(type(feature_train))  # numpy.ndarray

# 4. 机器学习（模型训练）
# 4.1 创建估计器，第一个参数是KNN算法的k值，默认为5， 第二个参数是KNN算法所采用的搜索方法，默认是auto，即自动选择brute（暴力搜索），kd_tree，ball_tree（超过20维用这个）中的一个
estimator = KNeighborsClassifier()

# 4.2 模型选择与调优--网格搜索和交叉验证，网格搜索是对超参数里的数据进行挨个遍历，交叉验证是将
# 训练集的数据再划分为训练集和测试集
param_dict = {'n_neighbors': [1, 3, 5, 7, 9]}
# 参数分别为：estimator：估计器，param_grid：手动输入的参数（knn中的k值，也叫作超参数），cv：表示将测试集数据分为10折进行测试，还有一个n_jobs：表示用CPU的几个核进行工作，如果为-1，直接跑满
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)

# 4.3 机器学习
estimator.fit(feature_train, dest_train)

# 5. 模型评估
# 5.1 模型测试
ret = estimator.predict(feature_test)
print('预测结果为:\n', ret)
print('预测的目标值和测试目标值对比:\n', ret == dest_test)

# 5.2 准确率
accuracy = estimator.score(feature_test, dest_test)
print('测试的准确率为:\n', accuracy)

# 5.3 结果分析
print("交叉验证中最好的结果是:\n", estimator.best_score_)
print("最好的参数模型是:\n", estimator.best_estimator_)
print("每次交叉验证后的准确率结果:\n", estimator.cv_results_)



